// 23_iterators.rs
// Rust 迭代器应用教程

fn main() {
    // 1. 基本迭代器概念
    println!("=== 1. 基本迭代器概念 ===");
    
    let v = vec![1, 2, 3, 4, 5];
    
    // iter() 创建不可变引用的迭代器
    for item in v.iter() {
        print!("{} ", item);
    }
    println!();
    
    // into_iter() 创建获取所有权的迭代器
    let v2 = vec![1, 2, 3];
    for item in v2.into_iter() {
        print!("{} ", item);
    }
    println!();
    // 注意：此时 v2 已经被移动，不能再使用
    
    // iter_mut() 创建可变引用的迭代器 
    let mut v3 = vec![1, 2, 3, 4, 5];
    for item in v3.iter_mut() {
        *item *= 2;
    }
    println!("修改后的v3: {:?}", v3);
    
    // 2. 迭代器适配器
    println!("\n=== 2. 迭代器适配器 ===");
    
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    // map: 对每个元素应用函数
    let doubled: Vec<i32> = numbers.iter().map(|x| x * 2).collect();
    println!("翻倍后的数字: {:?}", doubled);
    
    // filter: 过滤元素
    let evens: Vec<&i32> = numbers.iter().filter(|&x| x % 2 == 0).collect();
    println!("偶数: {:?}", evens);
    
    // filter_map: 过滤并转换
    let parsed_numbers: Vec<i32> = ["1", "2", "three", "4", "five"]
        .iter()
        .filter_map(|s| s.parse().ok())
        .collect();
    println!("解析成功的数字: {:?}", parsed_numbers);
    
    // take: 限制元素数量
    let first_five: Vec<i32> = (1..).take(5).collect();
    println!("前五个自然数: {:?}", first_five);
    
    // skip: 跳过元素
    let skipped: Vec<i32> = (1..10).skip(3).collect();
    println!("跳过前三个数: {:?}", skipped);
    
    // 3. 消费者适配器
    println!("\n=== 3. 消费者适配器 ===");
    
    let data = vec![1, 2, 3, 4, 5];
    
    // collect: 收集结果
    let collected: Vec<i32> = data.iter().map(|x| x * 2).collect();
    println!("收集结果: {:?}", collected);
    
    // fold: 累积计算
    let sum = data.iter().fold(0, |acc, x| acc + x);
    println!("使用fold计算总和: {}", sum);
    
    // reduce: 归约计算
    let product = data.iter().copied().reduce(|acc, x| acc * x);
    println!("使用reduce计算乘积: {:?}", product);
    
    // any: 检查是否有元素满足条件
    let has_even = data.iter().any(|x| x % 2 == 0);
    println!("是否有偶数: {}", has_even);
    
    // all: 检查是否所有元素都满足条件
    let all_positive = data.iter().all(|x| *x > 0);
    println!("是否所有数都是正数: {}", all_positive);
    
    // find: 查找第一个满足条件的元素
    let first_even = data.iter().find(|x| **x % 2 == 0);
    println!("第一个偶数: {:?}", first_even);
    
    // count: 计算元素数量
    let count = data.iter().count();
    println!("元素数量: {}", count);
    
    // max/min: 找到最大/最小值
    let max_val = data.iter().max();
    let min_val = data.iter().min();
    println!("最大值: {:?}, 最小值: {:?}", max_val, min_val);
    // max/min: 找到最大/最小值
    let data2 = vec![1, 2, 3, 4, 5];
    let max_val = data2.iter().max().unwrap_or(&0);
    let min_val = data2.iter().min().unwrap_or(&0);
    println!("最大值: {:?}, 最小值: {:?}", max_val, min_val);
    
    // 4. 链式调用
    println!("\n=== 4. 链式调用 ===");
    
    let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    
    // 链式调用示例：找到前5个偶数的平方
    let result: Vec<i32> = numbers
        .iter()
        .filter(|&x| x % 2 == 0)  // 过滤出偶数
        .take(5)                  // 取前5个
        .map(|x| x * x)           // 计算平方
        .collect();               // 收集结果
    println!("前5个偶数的平方: {:?}", result);
    
    // 5. 自定义迭代器
    println!("\n=== 5. 自定义迭代器 ===");
    
    struct Counter {
        current: usize,
        max: usize,
    }
    
    impl Counter {
        fn new(max: usize) -> Counter {
            Counter { current: 0, max }
        }
    }
    
    impl Iterator for Counter {
        type Item = usize;
        
        fn next(&mut self) -> Option<Self::Item> {
            if self.current < self.max {
                self.current += 1;
                Some(self.current)
            } else {
                None
            }
        }
    }
    
    let counter = Counter::new(5);
    for num in counter {
        print!("{} ", num);
    }
    println!();
    
    // 6. 迭代器与性能
    println!("\n=== 6. 迭代器与性能 ===");
    
    // 使用迭代器通常比手动循环更高效，因为编译器可以进行优化
    let data: Vec<i32> = (1..=1000000).collect();
    
    // 使用迭代器的方式
    let sum_iter: i64 = data.iter().map(|&x| x as i64).sum();
    println!("使用迭代器计算总和: {}", sum_iter);
    
    // 7. 常用迭代器方法
    println!("\n=== 7. 常用迭代器方法 ===");
    
    let words = vec!["apple", "banana", "cherry", "date"];
    
    // enumerate: 获取索引和值
    for (i, word) in words.iter().enumerate() {
        println!("{}: {}", i, word);
    }
    
    // zip: 合并两个迭代器
    let numbers = vec![1, 2, 3, 4];
    let letters = vec!['a', 'b', 'c', 'd'];
    for (num, letter) in numbers.iter().zip(letters.iter()) {
        println!("{}: {}", num, letter);
    }
    
    // flat_map: 展平嵌套结构
    let nested = vec![vec![1, 2], vec![3, 4], vec![5, 6]];
    let flattened: Vec<i32> = nested.iter().flat_map(|v| v.iter()).cloned().collect();
    println!("展平后的数组: {:?}", flattened);
    
    // 8. 迭代器与错误处理
    println!("\n=== 8. 迭代器与错误处理 ===");
    
    let strings = vec!["1", "2", "three", "4", "five", "6"];
    
    // collect with Result: 收集可能失败的操作结果
    let parsed: Result<Vec<i32>, _> = strings.iter().map(|s| s.parse::<i32>()).collect();
    match parsed {
        Ok(numbers) => println!("解析成功的数字: {:?}", numbers),
        Err(e) => println!("解析失败: {}", e),
    }
    
    // filter_map with Result: 过滤并转换可能失败的操作
    let valid_numbers: Vec<i32> = strings
        .iter()
        .filter_map(|s| s.parse::<i32>().ok())
        .collect();
    println!("有效的数字: {:?}", valid_numbers);
    
    // 新增：同时收集成功和失败的结果
    println!("\n=== 新增：同时收集成功和失败的结果 ===");
    let mut successes = Vec::new();
    let mut failures = Vec::new();
    
    for s in &strings {
        match s.parse::<i32>() {
            Ok(num) => successes.push(num),
            Err(e) => failures.push((s, e.to_string())),
        }
    }
    
    println!("解析成功的数字: {:?}", successes);
    println!("解析失败的字符串:");
    for (text, error) in &failures {
        println!("  '{}' - 错误: {}", text, error);
    }
    
    // 使用partition方法分离结果
    let (success_values, error_strings): (Vec<_>, Vec<_>) = strings
        .iter()
        .map(|s| (s, s.parse::<i32>()))
        .partition(|(_, result)| result.is_ok());
    
    let success_values: Vec<i32> = success_values.into_iter().map(|(_, result)| result.unwrap()).collect();
    let error_strings: Vec<(&str, String)> = error_strings.into_iter()
        .map(|(text, result)| (*text, result.unwrap_err().to_string()))
        .collect();
        
    println!("\n使用partition方法分离结果:");
    println!("解析成功的数字: {:?}", success_values);
    println!("解析失败的字符串:");
    for (text, error) in &error_strings {
        println!("  '{}' - 错误: {}", text, error);
    }
    
    // 使用fold一次遍历同时收集成功和失败的结果
    println!("\n使用fold方法一次遍历收集结果:");
    let (successes, failures) = strings.iter().fold(
        (Vec::new(), Vec::new()),
        |(mut successes, mut failures), s| {
            match s.parse::<i32>() {
                Ok(num) => {
                    successes.push(num);
                },
                Err(e) => {
                    failures.push((*s, e.to_string()));
                },
            }
            (successes, failures)
        },
    );
    
    println!("解析成功的数字: {:?}", successes);
    println!("解析失败的字符串:");
    for (text, error) in &failures {
        println!("  '{}' - 错误: {}", text, error);
    }
    
    // 改进的partition方法：一步到位收集成功和失败的结果
    println!("\n改进的partition方法：一步到位收集结果:");
    let start = std::time::Instant::now();
    let mut successes_improved = Vec::new();
    let mut failures_improved = Vec::new();
    
    let _: Vec<()> = strings
        .iter()
        .map(|s| s.parse::<i32>())
        .enumerate()
        .map(|(index, result)| {
            match result {
                Ok(num) => successes_improved.push(num),
                Err(_) => failures_improved.push(&strings[index]),
            }
        })
        .collect();
        
    let duration_improved = start.elapsed();
    println!("改进的partition方法耗时: {:?}", duration_improved);
    println!("解析成功的数字: {:?}", successes_improved);
    println!("解析失败的字符串数量: {}", failures_improved.len());
    
    // 更优雅的一次遍历方法：使用fold_with_index
    println!("\n更优雅的一次遍历方法:");
    let start = std::time::Instant::now();
    let (successes_elegant, failures_elegant) = strings
        .iter()
        .enumerate()
        .fold(
            (Vec::new(), Vec::new()),
            |(mut successes, mut failures), (index, s)| {
                match s.parse::<i32>() {
                    Ok(num) => successes.push(num),
                    Err(_) => failures.push(&strings[index]),
                }
                (successes, failures)
            },
        );
    let duration_elegant = start.elapsed();
    println!("更优雅的一次遍历方法耗时: {:?}", duration_elegant);
    println!("解析成功的数字: {:?}", successes_elegant);
    println!("解析失败的字符串数量: {}", failures_elegant.len());
    
    // 真正一步到位的partition方法：使用for_each避免collect浪费内存
    println!("\n真正一步到位的partition方法:");
    let start = std::time::Instant::now();
    let mut successes_one_step = Vec::new();
    let mut failures_one_step = Vec::new();
    
    strings
        .iter()
        .map(|s| s.parse::<i32>())
        .enumerate()
        .for_each(|(index, result)| {
            match result {
                Ok(num) => successes_one_step.push(num),
                Err(_) => failures_one_step.push(&strings[index]),
            }
        });
        
    let duration_one_step = start.elapsed();
    println!("真正一步到位的partition方法耗时: {:?}", duration_one_step);
    println!("解析成功的数字: {:?}", successes_one_step);
    println!("解析失败的字符串数量: {}", failures_one_step.len());
    
    // 性能比较测试
    println!("\n=== 性能比较测试 ===");
    let large_strings: Vec<String> = (1..1000000)
        .map(|i| {
            if i % 3 == 0 {
                format!("invalid{}", i)
            } else {
                i.to_string()
            }
        })
        .collect();
    
    // 方法1：基础方法（for循环 + match）
    let start = std::time::Instant::now();
    let mut successes1 = Vec::new();
    let mut failures1 = Vec::new();
    for s in &large_strings {
        match s.parse::<i32>() {
            Ok(num) => successes1.push(num),
            Err(_) => failures1.push(s),
        }
    }
    let duration1 = start.elapsed();
    println!("方法1（for循环 + match）耗时: {:?}", duration1);
    
    // 方法2：partition方法
    let start = std::time::Instant::now();
    let (success_values, _): (Vec<_>, Vec<_>) = large_strings
        .iter()
        .map(|s| (s, s.parse::<i32>()))
        .partition(|(_, result)| result.is_ok());
    let successes2: Vec<i32> = success_values.into_iter().map(|(_, result)| result.unwrap()).collect();
    let duration2 = start.elapsed();
    println!("方法2（partition方法）耗时: {:?}", duration2);
    
    // 方法3：fold方法
    let start = std::time::Instant::now();
    let (successes3, _): (Vec<i32>, Vec<(&String, String)>) = large_strings.iter().fold(
        (Vec::new(), Vec::new()),
        |(mut successes, mut failures), s| {
            match s.parse::<i32>() {
                Ok(num) => {
                    successes.push(num);
                },
                Err(e) => {
                    failures.push((s, e.to_string()));
                },
            }
            (successes, failures)
        },
    );
    let duration3 = start.elapsed();
    println!("方法3（fold方法）耗时: {:?}", duration3);
    
    // 方法4：改进的partition方法（一步到位）
    let start = std::time::Instant::now();
    let mut successes4 = Vec::new();
    let mut failures4 = Vec::new();
    let _: Vec<()> = large_strings
        .iter()
        .map(|s| s.parse::<i32>())
        .enumerate()
        .map(|(index, result)| {
            match result {
                Ok(num) => successes4.push(num),
                Err(_) => failures4.push(&large_strings[index]),
            }
        })
        .collect();
    let duration4 = start.elapsed();
    println!("方法4（改进的partition方法）耗时: {:?}", duration4);
    
    // 方法5：更优雅的一次遍历方法
    let start = std::time::Instant::now();
    let (successes5, _failures5) = large_strings
        .iter()
        .enumerate()
        .fold(
            (Vec::new(), Vec::new()),
            |(mut successes, mut failures), (index, s)| {
                match s.parse::<i32>() {
                    Ok(num) => successes.push(num),
                    Err(_) => failures.push(&large_strings[index]),
                }
                (successes, failures)
            },
        );
    let duration5 = start.elapsed();
    println!("方法5（更优雅的一次遍历方法）耗时: {:?}", duration5);
    
    // 方法6：真正一步到位的partition方法
    let start = std::time::Instant::now();
    let mut successes6 = Vec::new();
    let mut failures6 = Vec::new();
    
    large_strings
        .iter()
        .map(|s| s.parse::<i32>())
        .enumerate()
        .for_each(|(index, result)| {
            match result {
                Ok(num) => successes6.push(num),
                Err(_) => failures6.push(&large_strings[index]),
            }
        });
    let duration6 = start.elapsed();
    println!("方法6（真正一步到位的partition方法）耗时: {:?}", duration6);
    
    println!("六种方法收集到的成功结果数量: {}, {}, {}, {}, {}, {}", successes1.len(), successes2.len(), successes3.len(), successes4.len(), successes5.len(), successes6.len());
    
    // 性能分析总结
    println!("\n=== 性能分析总结 ===");
    println!("1. 方法1（for循环 + match）:");
    println!("   - 优点：直观易懂，只遍历一次，内存分配最少");
    println!("   - 缺点：命令式风格，不够函数式");
    println!("   - 适用场景：对性能要求高，数据量大的场景");
    println!("");
    println!("2. 方法2（partition方法）:");
    println!("   - 优点：函数式风格，代码简洁");
    println!("   - 缺点：需要两次遍历（partition一次，collect一次），内存使用较多");
    println!("   - 适用场景：数据量不大，注重代码可读性");
    println!("");
    println!("3. 方法3（fold方法）:");
    println!("   - 优点：函数式风格，只遍历一次");
    println!("   - 缺点：语法相对复杂");
    println!("   - 适用场景：需要函数式风格且对性能有一定要求");
    println!("");
    println!("4. 方法4（改进的partition方法）:");
    println!("   - 优点：函数式风格，只遍历一次");
    println!("   - 缺点：使用collect收集无用的Vec<()>，浪费内存");
    println!("   - 适用场景：需要函数式风格但想避免两次遍历");
    println!("");
    println!("5. 方法5（更优雅的一次遍历方法）:");
    println!("   - 优点：函数式风格，只遍历一次，无内存浪费");
    println!("   - 缺点：无明显缺点");
    println!("   - 适用场景：最佳平衡点，推荐使用");
    println!("");
    println!("6. 方法6（真正一步到位的partition方法）:");
    println!("   - 优点：函数式风格，只遍历一次，无内存浪费，避免collect");
    println!("   - 缺点：无明显缺点");
    println!("   - 适用场景：最佳平衡点，推荐使用");
    println!("");
    println!("性能排序（从高到低）：方法1 >= 方法5 ≈ 方法6 > 方法3 > 方法4 > 方法2");
    
    println!("\n迭代器是Rust中强大且高效的工具，它提供了函数式编程的风格，同时保持了零成本抽象的特性。");
}